﻿namespace DoNet.Common.Cache
{
    /// <summary>
    /// 缓存操作帮助类
    /// </summary>
    public class CacheHelper
    {
        /// <summary>
        /// 缓存提供模式
        /// </summary>
        private readonly CacheProvider cacheProvider;
        /// <summary>
        /// 缓存接口
        /// </summary>
        private readonly ICacheService? cacheservice;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        public CacheHelper(IServiceProvider serviceProvider)
        {
            var provider = serviceProvider.GetService(typeof(CacheProvider)) as CacheProvider;
            if (provider != null)
            {
                cacheProvider = provider;
                var iCacheService = serviceProvider.GetService(typeof(ICacheService)) as ICacheService;
                if (iCacheService != null)
                {
                    cacheservice = iCacheService;
                }
            }
            else
            {
                throw new ArgumentNullException(nameof(cacheProvider));
            }
        }

        /// <summary>
        /// 使用MemoryCache缓存操作
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <param name="isMemoryCache">是否使用MemoryCache</param>
        public CacheHelper(IServiceProvider serviceProvider, bool isMemoryCache = true)
        {
            var provider = serviceProvider.GetService(typeof(CacheProvider)) as CacheProvider;
            if (provider != null)
            {
                cacheProvider = provider;

                if (isMemoryCache)
                {
                    var memoryCacheService = serviceProvider.GetService(typeof(MemoryCacheService)) as MemoryCacheService;
                    if (memoryCacheService != null)
                    {
                        cacheservice = memoryCacheService;
                    }
                }
                else
                {
                    var iCacheService = serviceProvider.GetService(typeof(ICacheService)) as ICacheService;
                    if (iCacheService != null)
                    {
                        cacheservice = iCacheService;
                    }
                }
            }
            else
            {
                throw new ArgumentNullException(nameof(cacheProvider));
            }
        }

        #region 验证缓存项是否存在
        /// <summary>
        /// 验证缓存项是否存在,TryGetValue 来检测 Key是否存在的
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <returns></returns>
        public bool Exists(string key)
        {
            if (cacheservice == null)
                return false;
            return cacheservice.Exists(key);
        }
        #endregion

        #region 添加缓存

        /// <summary>
        /// 添加缓存
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <param name="value">缓存Value</param>
        /// <returns></returns>
        public bool Add(string key, object value)
        {
            if (cacheservice == null)
                return false;
            return cacheservice.Add(key, value);
        }
        /// <summary>
        /// 添加缓存
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <param name="value">缓存Value</param>
        /// <param name="expiresSliding">滑动过期时长（如果在过期时间内有操作，则以当前时间点延长过期时间）</param>
        /// <param name="expiressAbsoulte">绝对过期时长</param>
        /// <returns></returns>
        public bool Add(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
        {
            if (cacheservice == null)
                return false;
            return cacheservice.Add(key, value, expiresSliding, expiressAbsoulte);
        }
        /// <summary>
        /// 添加缓存
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <param name="value">缓存Value</param>
        /// <param name="expiresIn">缓存时长</param>
        /// <param name="isSliding">是否滑动过期（如果在过期时间内有操作，则以当前时间点延长过期时间）</param>
        /// <returns></returns>
        public bool Add(string key, object value, TimeSpan expiresIn, bool isSliding = false)
        {
            if (cacheservice == null)
                return false;
            return cacheservice.Add(key, value, expiresIn, isSliding);
        }
        #endregion

        #region 删除缓存

        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <returns></returns>
        public bool Remove(string key)
        {
            if (cacheservice == null)
                return false;
            return cacheservice.Remove(key);
        }
        /// <summary>
        /// 批量删除缓存
        /// </summary>
        /// <param name="keys">缓存Key集合</param>
        /// <returns></returns>
        public void RemoveAll(IEnumerable<string> keys)
        {
            if (cacheservice != null)
                cacheservice.RemoveAll(keys);
        }
        /// <summary>
        /// 删除匹配到的缓存
        /// </summary>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public void RemoveByPattern(string pattern)
        {
            if (cacheservice != null)
                cacheservice.RemoveByPattern(pattern);
        }
        /// <summary>
        /// 删除所有缓存
        /// </summary>
        public void RemoveCacheAll()
        {
            if (cacheservice != null)
                cacheservice.RemoveCacheAll();
        }
        #endregion

        #region 获取缓存
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <returns></returns>
        public T? Get<T>(string key) where T : class
        {
            if (cacheservice == null)
                return default;
            return cacheservice.GetByKey<T>(key);
        }
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <returns></returns>
        public object? Get(string key)
        {
            if (cacheservice == null)
                return default;
            return cacheservice.GetByKey(key);
        }
        /// <summary>
        /// 获取缓存集合
        /// </summary>
        /// <param name="keys">缓存Key集合</param>
        /// <returns></returns>
        public IDictionary<string, object>? GetAll(IEnumerable<string> keys)
        {
            if (cacheservice == null)
                return default;
            return cacheservice.GetAll(keys);
        }

        #endregion

        #region 修改缓存
        /// <summary>
        /// 修改缓存
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <param name="value">新的缓存Value</param>
        /// <returns></returns>
        public bool Replace(string key, object value)
        {
            if (cacheservice == null)
                return false;
            return cacheservice.Replace(key, value);

        }
        /// <summary>
        /// 修改缓存
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <param name="value">新的缓存Value</param>
        /// <param name="expiresSliding">滑动过期时长（如果在过期时间内有操作，则以当前时间点延长过期时间）</param>
        /// <param name="expiressAbsoulte">绝对过期时长</param>
        /// <returns></returns>
        public bool Replace(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
        {
            if (cacheservice == null)
                return false;
            return cacheservice.Replace(key, value, expiresSliding, expiressAbsoulte);
        }
        /// <summary>
        /// 修改缓存
        /// </summary>
        /// <param name="key">缓存Key</param>
        /// <param name="value">新的缓存Value</param>
        /// <param name="expiresIn">缓存时长</param>
        /// <param name="isSliding">是否滑动过期（如果在过期时间内有操作，则以当前时间点延长过期时间）</param>
        /// <returns></returns>
        public bool Replace(string key, object value, TimeSpan expiresIn, bool isSliding = false)
        {
            if (cacheservice == null)
                return false;
            return cacheservice.Replace(key, value, expiresIn, isSliding);
        }
        #endregion
    }
}
